"""
Grave! Important! Важно!

Proletoj el ĉiuj landoj, unuiĝu!
Workers of the world, unite!
Пролетарии всех стран, соединяйтесь!

https://tkom.pro
"""

import sys
import random, string
from django.db import models
from django.db.models import Q, Max
from django.contrib.auth.models import Permission
from django.utils.translation import gettext_lazy as _
from informiloj.models import InformilojLingvo, InformilojLando, InformilojRegiono, InformilojLaborarolo, \
    InformilojSciigoTipo, InformilojRegionoTeknokomo
from main.models import SiriusoBazaAbstrakta, SiriusoBazaAbstraktaKomunumoj, \
    SiriusoTipoAbstrakta, SiriusoSlugo, SiriusoAutomataKreinto
from siriuso.models.postgres import CallableEncoder
from siriuso.utils import default_lingvo, get_enhavo
from main.models import SpecialajGrupoj

import functools


def komunumoj_bildo_nomo(instance, filename, tipo='avataroj'):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'komunumoj/{}/bildoj/{}.{}'.format(tipo, rnd_string, filename.split('.')[-1])


komunumoj_avataro_nomo = functools.partial(komunumoj_bildo_nomo, tipo='avataroj')
komunumoj_kovrilo_nomo = functools.partial(komunumoj_bildo_nomo, tipo='kovriloj')
komunumoj_informo_bildo_nomo = functools.partial(komunumoj_bildo_nomo, tipo='informoj')


# 2. Варианты доступа (видимости) к сущностям сообщества, использует абстрактный класс SiriusoBazaAbstrakta
class KomunumojAliro(SiriusoTipoAbstrakta):
    # Обозначения доступов
    nomo = models.JSONField(verbose_name=_('Nomo'), blank=True, null=False, default=default_lingvo,
                              encoder=CallableEncoder)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj_aliroj'
        # читабельное название модели, в единственном числе
        verbose_name = _('Aliro')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Aliroj')

    # выбор объекта для отображения в интерфейсах, в том числе администратора
    def __str__(self):
        # для представления объекта будет выведено поле nomo этой модели
        return '{}'.format(get_enhavo(self.nomo, empty_values=True)[0])


# 3. Абстрактный класс сообществ, использует абстрактный класс SiriusoBazaAbstraktaKomunumoj
class KomunumojAbstrakta(SiriusoBazaAbstraktaKomunumoj):
    # ID записи для вывода
    id = models.IntegerField(_('ID'), unique=True, default=0)

    # важное сообщество (да или нет)
    grava = models.BooleanField(_('Grava'), default=False)

    # слаг
    slugo = models.OneToOneField(SiriusoSlugo, verbose_name=_('Slugo'), blank=True, null=True, on_delete=models.CASCADE)

    # дополнительные настройки для модели
    class Meta:
        # указание что это абстрактный класс
        abstract = True

    # выбор объекта для отображения в интерфейсах, в том числе администратора
    def __str__(self):
        # для представления объекта будет выведено поле nomo модели
        return '{}'.format(get_enhavo(self.nomo, empty_values=True)[0])

    # реализация автоинкремента при сохранении
    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        if self.id is None or not self.id:
            model = getattr(sys.modules[self.__module__], self.__class__.__name__)
            next_id = model.objects.all().aggregate(Max('id'))['id__max']

            if next_id is None:
                next_id = 1
            else:
                next_id += 1
            super(model, self).__setattr__('id', next_id)

        super(KomunumojAbstrakta, self).save(force_insert=force_insert, force_update=force_update, using=using,
                                             update_fields=update_fields)


#######################################
# Модель сообществ
class KomunumoUnuixo(SiriusoBazaAbstraktaKomunumoj):
    nomo = models.JSONField(verbose_name=_('Nomo'), blank=True, null=False, default=default_lingvo,
                              encoder=CallableEncoder)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj_unuixo'
        # читабельное название модели, в единственном числе
        verbose_name = _('Unuiĝo de komunumoj')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Unuiĝoj de komunumoj')

    # выбор объекта для отображения в интерфейсах, в том числе администратора
    def __str__(self):
        # для представления объекта будет выведено поле nomo модели
        return '{}'.format(get_enhavo(self.nomo, empty_values=True)[0])


# Типы сообществ
class KomunumoTipo(SiriusoTipoAbstrakta):
    kodo = models.CharField(_('Kodo'), max_length=64)

    nomo = models.JSONField(verbose_name=_('Nomo'), blank=True, null=False, default=default_lingvo,
                              encoder=CallableEncoder)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj_tipoj'
        # читабельное название модели, в единственном числе
        verbose_name = _('Tipo de komunumoj')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Tipoj de komunumoj')


# Виды сообществ
class KomunumoSpeco(SiriusoTipoAbstrakta):
    kodo = models.CharField(_('Kodo'), max_length=64)

    nomo = models.JSONField(verbose_name=_('Nomo'), blank=True, null=False, default=default_lingvo,
                              encoder=CallableEncoder)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj_specoj'
        # читабельное название модели, в единственном числе
        verbose_name = _('Speco de komunumoj')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Specoj de komunumoj')


class KomunumoKategorio(SiriusoBazaAbstraktaKomunumoj):
    # название в таблице названий категорий, от туда будет браться название с нужным языковым тегом
    nomo = models.JSONField(verbose_name=_('Titolo'), blank=True, null=False, default=default_lingvo,
                              encoder=CallableEncoder)

    # описание в таблице описаний категорий, от туда будет браться описание с нужным языковым тегом
    priskribo = models.JSONField(verbose_name=_('Priskribo'), blank=True, null=False, default=default_lingvo,
                                   encoder=CallableEncoder)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj_kategorioj'
        # читабельное название модели, в единственном числе
        verbose_name = _('Kategorio de komunumoj')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Kategorioj de komunumoj')


# Сообщества
class Komunumo(KomunumojAbstrakta, SiriusoAutomataKreinto):
    # объединение сообществ
    unuixo = models.ForeignKey(KomunumoUnuixo, verbose_name=_('Unuiĝo'), blank=True, null=True,
                               related_name='%(app_label)s_%(class)s_unuixo',
                               on_delete=models.CASCADE)

    # тип
    tipo = models.ForeignKey(KomunumoTipo, verbose_name=_('Tipo'), blank=False, default=None,
                             related_name='%(app_label)s_%(class)s_tipo',
                             on_delete=models.CASCADE)

    # вид
    speco = models.ForeignKey(KomunumoSpeco, verbose_name=_('Speco'), blank=False, default=None, null=True,
                              related_name='%(app_label)s_%(class)s_speco',
                              on_delete=models.SET_NULL)

    kategorioj = models.ManyToManyField(KomunumoKategorio, verbose_name=_('Kategorioj'), blank=True,
                                        db_table='komunumoj_kategorioj_kohero')

    # Cвязь с родителем
    posedanto = models.ForeignKey('self', verbose_name=_('Posedanto'), blank=True, null=True,
                                  related_name='%(app_label)s_%(class)s_posedanto',
                                  on_delete=models.SET_NULL)

    # название
    nomo = models.JSONField(verbose_name=_('Titolo'), blank=True, null=False, default=default_lingvo,
                              encoder=CallableEncoder)

    # описание
    priskribo = models.JSONField(verbose_name=_('Priskribo'), blank=True, null=False, default=default_lingvo,
                                   encoder=CallableEncoder)

    # статус сообщества
    statuso = models.JSONField(verbose_name=_('Statuso'), blank=True, null=False, default=default_lingvo,
                                   encoder=CallableEncoder)

    # страна
    lando = models.ForeignKey(InformilojLando, verbose_name=_('Lando'), blank=True, null=True,
                              related_name='%(app_label)s_%(class)s_lando',
                              on_delete=models.CASCADE)

    # регион
    regiono = models.ForeignKey(InformilojRegiono, verbose_name=_('Regiono'), blank=True, null=True,
                                related_name='%(app_label)s_%(class)s_regiono',
                                on_delete=models.CASCADE)

    # регион технокома
    regiono_teknokomo = models.ForeignKey(InformilojRegionoTeknokomo, verbose_name=_('Regiono de Teknokomo'),
                                          related_name='%(app_label)s_%(class)s_regiono_teknokomo',
                                          blank=True, null=True, on_delete=models.CASCADE)

    kohereco = models.ManyToManyField('self', verbose_name=_('Komunumaj ligoj'), blank=True,
                                      db_table='komunumoj_koherecoj')

    # закреплен (да или нет)
    fiksa = models.BooleanField(_('Fiksa'), blank=True, default=False)

    # позиция среди закреплённых
    fiksa_listo = models.IntegerField(_('Fiksa listo'), blank=True, null=True)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj'
        # читабельное название модели, в единственном числе
        verbose_name = _('Komunumo')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Komunumoj')
        # права
        permissions = (
            ('povas_vidi_komunumon', _('Povas vidi komunumon')),
            ('povas_krei_komunumon', _('Povas krei komunumon')),
            ('povas_forigi_komunumon', _('Povas forigu komunumon')),
            ('povas_shanghi_komunuman_specon', _('Povas ŝanĝi komunuman specon')),
            ('povas_shanghi_komunumajn_kategoriojn', _('Povas ŝanĝi komunumajn kategoriojn')),
            ('povas_shanghi_komunuman_avataron', _('Povas ŝanĝi komunuman avataron')),
            ('povas_shanghi_komunuman_kovrilon', _('Povas ŝanĝi komunuman kovrilon')),
            ('povas_shanghi_komunuman_nomon', _('Povas ŝanĝi komunuman nomon')),
            ('povas_shanghi_komunuman_priskribon', _('Povas ŝanĝi komunuman priskribon')),
            ('povas_shanghi_komunuman_statuson', _('Povas ŝanĝi komunuman statuson')),
        )

    def _get_user_permissions(self, user_obj):
        perms = Permission.objects.none()

        if user_obj.is_authenticated and user_obj.is_active:
            if user_obj.is_superuser:
                perms = Permission.objects.filter(content_type__app_label__in=['komunumoj', 'muroj'])
            else:
                try:
                    membro = KomunumoMembro.objects.select_related('tipo').get(
                        posedanto=self, autoro=user_obj, forigo=False
                    )

                    if membro.tipo.kodo in ('administranto', 'komunumano-adm'):
                        grupoj = SpecialajGrupoj.objects.get(kodo='komunumano-adm').grupoj.all()
                    elif membro.tipo.kodo in ('moderiganto', 'komunumano-mod'):
                        grupoj = SpecialajGrupoj.objects.get(kodo='kom_moderiganto').grupoj.all()
                    else:
                        grupoj = SpecialajGrupoj.objects.none()

                    if grupoj:
                        for grupo in grupoj:
                            perms |= grupo.permissions.filter(content_type__app_label__in=['komunumoj', 'muroj'])
                except (KomunumoMembro.DoesNotExist, SpecialajGrupoj.DoesNotExist):
                    pass

        return perms

    def _get_group_permissions(self, user_obj):
        return Permission.objects.none()

    @staticmethod
    def _get_perm_cond(user_obj):
        if user_obj.has_perm('komunumoj.povas_vidi_komunumon'):
            cond = Q(forigo=False, publikigo=True, arkivo=False)
        else:
            cond = Q(uuid__isnull=True)

        return cond


# Данные по рейтингу Сообществ
class KomunumoTakso(SiriusoBazaAbstrakta):
    # ссылка на сообщество
    komunumo = models.ForeignKey(Komunumo, verbose_name=_('Takso'), blank=False, default=None,
                                 related_name='%(app_label)s_%(class)s_komunumo',
                                 on_delete=models.CASCADE)
    # рейтинг
    takso = models.IntegerField(_('Takso'), default=0, db_index=True)
    # дата рейтинга
    takso_dato = models.DateField(_('Dato de takso'), blank=False, db_index=True)
    # дата последней активности
    aktiva_dato = models.DateField(_('Aktiva dato'), blank=True)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj_taksoj'
        # читабельное название модели, в единственном числе
        verbose_name = _('Takso de komunumo')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Taksoj de komunumoj')

    # выбор объекта для отображения в интерфейсах, в том числе администратора
    def __str__(self):
        # для представления объекта будет выведено поле uuid этой модели
        return '{} ({}): {}'.format(self.komunumo, self.uuid, self.takso)


# Типы членов сообществ, использует абстрактный класс SiriusoTipoAbstrakta
class KomunumoMembroTipo(SiriusoTipoAbstrakta):
    # название в таблице названий типов, от туда будет браться название с нужным языковым тегом
    nomo = models.JSONField(verbose_name=_('Nomo'), blank=True, null=False, default=default_lingvo,
                              encoder=CallableEncoder)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj_membroj_tipoj'
        # читабельное название модели, в единственном числе
        verbose_name = _('Tipo de membroj de sovetoj')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Tipoj de membroj de sovetoj')


# Члены советов и настройки уведомлений членов, использует абстрактный класс SiriusoBazaAbstraktaKomunumoj
class KomunumoMembro(SiriusoBazaAbstraktaKomunumoj):
    # владелец (совет)
    posedanto = models.ForeignKey(Komunumo, verbose_name=_('Posedanto'), blank=False, default=None,
                                  related_name='%(app_label)s_%(class)s_posedanto',
                                  on_delete=models.CASCADE)

    # тип члена совета
    tipo = models.ForeignKey(KomunumoMembroTipo, verbose_name=_('Tipo'), blank=False, default=None,
                             related_name='%(app_label)s_%(class)s_tipo',
                             on_delete=models.CASCADE)

    # трудовая роль
    laborarolo = models.ForeignKey(InformilojLaborarolo, verbose_name=_('Laborarolo'), blank=True, null=True,
                                   related_name='%(app_label)s_%(class)s_laborarolo',
                                   on_delete=models.CASCADE)

    # контактное лицо (да или нет)
    kontaktulo = models.BooleanField(_('Kontaktulo'), default=False)

    # контактная информация
    kontakta_informo = models.TextField(_('Kontakta informo'), blank=True, null=True)

    # уведомления о записях на стене
    muro_sciigo = models.ManyToManyField(InformilojSciigoTipo, verbose_name=_('Sciigo (muro)'), blank=True)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj_membroj'
        # читабельное название модели, в единственном числе
        verbose_name = _('Membro de komunumo')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Membroj de komunumoj')

    # выбор объекта для отображения в интерфейсах, в том числе администратора
    def __str__(self):
        # для представления объекта будет выведено поле autoro этой модели
        return '{}'.format(self.autoro)


# Краткая информация о сообществе
class KomunumoInformo(SiriusoBazaAbstraktaKomunumoj):
    # владелец
    posedanto = models.OneToOneField(Komunumo, verbose_name=_('Posedanto'), blank=False, default=None,
                                     on_delete=models.CASCADE)

    # текст в таблице текстов краткой информации, от туда будет браться текст с нужным языковым тегом
    teksto = models.JSONField(verbose_name=_('Teksto'), blank=True, null=False, default=default_lingvo,
                                encoder=CallableEncoder)

    # ссылка на подробную информацию в энциклопедии
    ligilo = models.URLField(_('Ligilo'), max_length=200, blank=True)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj_informoj'
        # читабельное название модели, в единственном числе
        verbose_name = _('Informo de komunumo')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Informo de komunumoj')

    # выбор объекта для отображения в интерфейсах, в том числе администратора
    def __str__(self):
        # для представления объекта будет выведено поле uuid модели
        return '{}'.format(self.uuid)


# Изображения информации о сообществах, использует абстрактный класс SiriusoBazaAbstraktaKomunumoj
class KomunumoInformoBildo(SiriusoBazaAbstraktaKomunumoj):
    # владелец (информация сообщества)
    posedanto = models.ForeignKey(KomunumoInformo, verbose_name=_('Posedanto'), blank=False, default=None,
                                  related_name='%(app_label)s_%(class)s_posedanto',
                                  on_delete=models.CASCADE)

    # изображение для отображения (нужно сделать размер до 1280x1024 включительно)
    bildo = models.ImageField(_('Bildo'), upload_to=komunumoj_informo_bildo_nomo, blank=False,
                              default=None)

    # дополнительные настройки для модели
    class Meta:
        # название таблицы в базе данных для этой модели
        db_table = 'komunumoj_informo_bildoj'
        # читабельное название модели, в единственном числе
        verbose_name = _('Bildo')
        # читабельное название модели, во множественном числе
        verbose_name_plural = _('Bildoj')

    # выбор объекта для отображения в интерфейсах, в том числе администратора
    def __str__(self):
        # для представления объекта будет выведено поле posedanto модели
        return '{}'.format(self.posedanto)


#######################################
# 1. Генерация случайного названия и переименование загружаемых картинок аватар советов
def komunumoj_soveto_avataro_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'sovetoj/avataroj/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 2. Генерация случайного названия и переименование загружаемых картинок обложек советов
def komunumoj_soveto_kovrilo_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'sovetoj/kovriloj/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 3. Генерация случайного названия и переименование загружаемых картинок информации о советах
def komunumoj_soveto_informo_bildo_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'sovetoj/informo/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 4. Генерация случайного названия и переименование загружаемых картинок аватар групп
def komunumoj_grupo_avataro_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'grupoj/avataroj/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 5. Генерация случайного названия и переименование загружаемых картинок обложек групп
def komunumoj_grupo_kovrilo_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'grupoj/kovriloj/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 6. Генерация случайного названия и переименование загружаемых картинок информации о группах
def komunumoj_grupo_informo_bildo_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'grupoj/informo/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 7. Генерация случайного названия и переименование загружаемых картинок аватар организаций
def komunumoj_organizo_avataro_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'organizoj/avataroj/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 8. Генерация случайного названия и переименование загружаемых картинок обложек организаций
def komunumoj_organizo_kovrilo_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'organizoj/kovriloj/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 9. Генерация случайного названия и переименование загружаемых картинок информации об организациях
def komunumoj_organizo_informo_bildo_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'organizoj/informo/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 10. Генерация случайного названия и переименование загружаемых картинок аватар коллективных блогов
def komunumoj_kolektivablogo_avataro_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'kolektivablogoj/avataroj/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 11. Генерация случайного названия и переименование загружаемых картинок обложек коллективных блогов
def komunumoj_kolektivablogo_kovrilo_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'kolektivablogoj/kovriloj/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 12. Генерация случайного названия и переименование загружаемых картинок аватар общественных проектов
def komunumoj_sociaprojekto_avataro_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'sociaprojektoj/avataroj/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 13. Генерация случайного названия и переименование загружаемых картинок обложек общественных проектов
def komunumoj_sociaprojekto_kovrilo_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'sociaprojektoj/kovriloj/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])


# 14. Генерация случайного названия и переименование загружаемых картинок информации об общественных проектах
def komunumoj_sociaprojekto_informo_bildo_nomo(instance, filename):
    letters = string.ascii_letters + string.digits
    rnd_string = ''.join(random.choice(letters) for i in range(10))
    # указание папки для хранения файлов и собирание конечного названия с сохранением изначального расширения
    return 'sociaprojektoj/informo/bildoj/{0}.{1}'.format(rnd_string, filename.split('.')[-1])
